/**
 * 银行卡验证工具类
 * 包含银行卡号验证、银行名称标准化、BIN码识别等功能
 */

// 银行BIN码对照表（前6位）
const BANK_BIN_MAP = {
  // 工商银行
  '102801': '中国工商银行',
  '102802': '中国工商银行',
  '102803': '中国工商银行',
  '622200': '中国工商银行',
  '622202': '中国工商银行',
  '622203': '中国工商银行',
  '622208': '中国工商银行',
  '955880': '中国工商银行',
  '621225': '中国工商银行',
  '621226': '中国工商银行',
  '621227': '中国工商银行',
  '621281': '中国工商银行',
  '621288': '中国工商银行',
  '621721': '中国工商银行',
  '621722': '中国工商银行',
  '621723': '中国工商银行',
  
  // 农业银行
  '103000': '中国农业银行',
  '622848': '中国农业银行',
  '622849': '中国农业银行',
  '622850': '中国农业银行',
  '622851': '中国农业银行',
  '622852': '中国农业银行',
  '622853': '中国农业银行',
  '622854': '中国农业银行',
  '622855': '中国农业银行',
  '622856': '中国农业银行',
  '622857': '中国农业银行',
  '622858': '中国农业银行',
  '622859': '中国农业银行',
  '622860': '中国农业银行',
  '621671': '中国农业银行',
  '621672': '中国农业银行',
  
  // 中国银行
  '104000': '中国银行',
  '621660': '中国银行',
  '621661': '中国银行',
  '621662': '中国银行',
  '621663': '中国银行',
  '621665': '中国银行',
  '621667': '中国银行',
  '621668': '中国银行',
  '621669': '中国银行',
  '621666': '中国银行',
  '456351': '中国银行',
  '601382': '中国银行',
  '622752': '中国银行',
  '622753': '中国银行',
  '622755': '中国银行',
  '622756': '中国银行',
  
  // 建设银行
  '105000': '中国建设银行',
  '621700': '中国建设银行',
  '621701': '中国建设银行',
  '621702': '中国建设银行',
  '621703': '中国建设银行',
  '621704': '中国建设银行',
  '621705': '中国建设银行',
  '621706': '中国建设银行',
  '621707': '中国建设银行',
  '621708': '中国建设银行',
  '621709': '中国建设银行',
  '621710': '中国建设银行',
  '621711': '中国建设银行',
  '356869': '中国建设银行',
  '356868': '中国建设银行',
  '622280': '中国建设银行',
  
  // 交通银行
  '301000': '交通银行',
  '622260': '交通银行',
  '622261': '交通银行',
  '622262': '交通银行',
  '622263': '交通银行',
  '622264': '交通银行',
  '622265': '交通银行',
  '622266': '交通银行',
  '622267': '交通银行',
  '622268': '交通银行',
  '622269': '交通银行',
  '622258': '交通银行',
  '622259': '交通银行',
  '521899': '交通银行',
  
  // 招商银行
  '308000': '招商银行',
  '621483': '招商银行',
  '621485': '招商银行',
  '621486': '招商银行',
  '356885': '招商银行',
  '356886': '招商银行',
  '356887': '招商银行',
  '356888': '招商银行',
  '356889': '招商银行',
  '356890': '招商银行',
  '622575': '招商银行',
  '622576': '招商银行',
  '622577': '招商银行',
  '622578': '招商银行',
  '622579': '招商银行',
  '622580': '招商银行',
  '622581': '招商银行',
  '622582': '招商银行',
  '622588': '招商银行',
  '622598': '招商银行',
  
  // 浦发银行
  '310000': '上海浦东发展银行',
  '621998': '上海浦东发展银行',
  '621999': '上海浦东发展银行',
  '622516': '上海浦东发展银行',
  '622517': '上海浦东发展银行',
  '622518': '上海浦东发展银行',
  '404738': '上海浦东发展银行',
  '404739': '上海浦东发展银行',
  '498451': '上海浦东发展银行',
  '515672': '上海浦东发展银行',
  '517650': '上海浦东发展银行',
  '525998': '上海浦东发展银行',
  '622521': '上海浦东发展银行',
  
  // 民生银行
  '305000': '中国民生银行',
  '622600': '中国民生银行',
  '622601': '中国民生银行',
  '622602': '中国民生银行',
  '622603': '中国民生银行',
  '415599': '中国民生银行',
  '421393': '中国民生银行',
  '421865': '中国民生银行',
  '421869': '中国民生银行',
  '421870': '中国民生银行',
  '622615': '中国民生银行',
  '622617': '中国民生银行',
  '622619': '中国民生银行',
  '622622': '中国民生银行',
  
  // 兴业银行
  '309391': '兴业银行',
  '622902': '兴业银行',
  '622901': '兴业银行',
  '486493': '兴业银行',
  '486494': '兴业银行',
  '523952': '兴业银行',
  '356859': '兴业银行',
  '486861': '兴业银行',
  '523036': '兴业银行',
  '438125': '兴业银行',
  '438126': '兴业银行',
  '451289': '兴业银行',
  '527414': '兴业银行',
  
  // 光大银行
  '303000': '中国光大银行',
  '622650': '中国光大银行',
  '622655': '中国光大银行',
  '622658': '中国光大银行',
  '622660': '中国光大银行',
  '356837': '中国光大银行',
  '356838': '中国光大银行',
  '356839': '中国光大银行',
  '356840': '中国光大银行',
  '406252': '中国光大银行',
  '406254': '中国光大银行',
  '481699': '中国光大银行',
  
  // 中信银行
  '302000': '中信银行',
  '622678': '中信银行',
  '622679': '中信银行',
  '622680': '中信银行',
  '622688': '中信银行',
  '622689': '中信银行',
  '622690': '中信银行',
  '622691': '中信银行',
  '622692': '中信银行',
  '622696': '中信银行',
  '622698': '中信银行',
  '400360': '中信银行',
  '403391': '中信银行',
  '404157': '中信银行',
  '404171': '中信银行',
  '404172': '中信银行',
  '404173': '中信银行',
  '404174': '中信银行',
  '421437': '中信银行',
  
  // 华夏银行
  '304000': '华夏银行',
  '622630': '华夏银行',
  '622631': '华夏银行',
  '622632': '华夏银行',
  '622633': '华夏银行',
  '539867': '华夏银行',
  '539868': '华夏银行',
  '528709': '华夏银行',
  '622637': '华夏银行',
  '622638': '华夏银行',
  '622639': '华夏银行',
  
  // 广发银行
  '306000': '广发银行',
  '622525': '广发银行',
  '622526': '广发银行',
  '406365': '广发银行',
  '520152': '广发银行',
  '520382': '广发银行',
  '541709': '广发银行',
  '541710': '广发银行',
  '548844': '广发银行',
  '552794': '广发银行',
  '622568': '广发银行',
  
  // 平安银行
  '307000': '平安银行',
  '622155': '平安银行',
  '622156': '平安银行',
  '622157': '平安银行',
  '622158': '平安银行',
  '622159': '平安银行',
  '627066': '平安银行',
  '627067': '平安银行',
  '627068': '平安银行',
  '998800': '平安银行',
  '998801': '平安银行',
  '998802': '平安银行',
  
  // 深发银行
  '307001': '深发银行',
  '622538': '深发银行',
  '412962': '深发银行',
  '412963': '深发银行',
  '622525': '深发银行',
  '622526': '深发银行'
};

// 银行名称标准化字典
const BANK_NAME_MAP = {
  // 工商银行
  '工商银行': '中国工商银行',
  '工行': '中国工商银行',
  'ICBC': '中国工商银行',
  '中国工商银行': '中国工商银行',
  '工商银行股份有限公司': '中国工商银行',
  
  // 农业银行
  '农业银行': '中国农业银行',
  '农行': '中国农业银行',
  'ABC': '中国农业银行',
  '中国农业银行': '中国农业银行',
  '农业银行股份有限公司': '中国农业银行',
  
  // 中国银行
  '中国银行': '中国银行',
  '中行': '中国银行',
  'BOC': '中国银行',
  '中国银行股份有限公司': '中国银行',
  
  // 建设银行
  '建设银行': '中国建设银行',
  '建行': '中国建设银行',
  'CCB': '中国建设银行',
  '中国建设银行': '中国建设银行',
  '建设银行股份有限公司': '中国建设银行',
  
  // 交通银行
  '交通银行': '交通银行',
  '交行': '交通银行',
  'BOCOM': '交通银行',
  '交通银行股份有限公司': '交通银行',
  
  // 招商银行
  '招商银行': '招商银行',
  '招行': '招商银行',
  'CMB': '招商银行',
  '招商银行股份有限公司': '招商银行',
  
  // 浦发银行
  '浦发银行': '上海浦东发展银行',
  '浦东发展银行': '上海浦东发展银行',
  '上海浦发银行': '上海浦东发展银行',
  '上海浦东发展银行': '上海浦东发展银行',
  'SPDB': '上海浦东发展银行',
  
  // 民生银行
  '民生银行': '中国民生银行',
  '中国民生银行': '中国民生银行',
  'CMBC': '中国民生银行',
  '民生银行股份有限公司': '中国民生银行',
  
  // 兴业银行
  '兴业银行': '兴业银行',
  'CIB': '兴业银行',
  '兴业银行股份有限公司': '兴业银行',
  
  // 光大银行
  '光大银行': '中国光大银行',
  '中国光大银行': '中国光大银行',
  'CEB': '中国光大银行',
  '光大银行股份有限公司': '中国光大银行',
  
  // 中信银行
  '中信银行': '中信银行',
  'CITIC': '中信银行',
  '中信银行股份有限公司': '中信银行',
  '中信实业银行': '中信银行',
  
  // 华夏银行
  '华夏银行': '华夏银行',
  'HXB': '华夏银行',
  '华夏银行股份有限公司': '华夏银行',
  
  // 广发银行
  '广发银行': '广东发展银行',
  '广东发展银行': '广东发展银行',
  'GDB': '广东发展银行',
  '广发银行股份有限公司': '广东发展银行',
  
  // 平安银行
  '平安银行': '平安银行',
  'PAB': '平安银行',
  '平安银行股份有限公司': '平安银行',
  '深圳平安银行': '平安银行',
  
  // 深发银行
  '深发银行': '深圳发展银行',
  '深圳发展银行': '深圳发展银行',
  'SDB': '深圳发展银行'
};

/**
 * Luhn算法验证银行卡号
 * @param {string} cardNumber 银行卡号
 * @returns {boolean} 是否通过验证
 */
function luhnCheck(cardNumber) {
  if (!cardNumber || typeof cardNumber !== 'string') {
    return false;
  }
  
  // 移除空格和非数字字符
  const cleanNumber = cardNumber.replace(/\D/g, '');
  
  if (cleanNumber.length < 13 || cleanNumber.length > 19) {
    return false;
  }
  
  let sum = 0;
  let isEven = false;
  
  // 从右到左遍历
  for (let i = cleanNumber.length - 1; i >= 0; i--) {
    let digit = parseInt(cleanNumber.charAt(i));
    
    if (isEven) {
      digit *= 2;
      if (digit > 9) {
        digit = digit % 10 + Math.floor(digit / 10);
      }
    }
    
    sum += digit;
    isEven = !isEven;
  }
  
  return sum % 10 === 0;
}

/**
 * 根据BIN码识别银行
 * @param {string} cardNumber 银行卡号
 * @returns {string|null} 银行名称
 */
function getBankByBIN(cardNumber) {
  if (!cardNumber || typeof cardNumber !== 'string') {
    return null;
  }
  
  const cleanNumber = cardNumber.replace(/\D/g, '');
  
  if (cleanNumber.length < 6) {
    return null;
  }
  
  const bin6 = cleanNumber.substring(0, 6);
  
  return BANK_BIN_MAP[bin6] || null;
}

/**
 * 标准化银行名称
 * @param {string} bankName 银行名称
 * @returns {string|null} 标准化后的银行名称
 */
function standardizeBankName(bankName) {
  if (!bankName || typeof bankName !== 'string') {
    return null;
  }
  
  const trimmedName = bankName.trim();
  
  // 精确匹配
  if (BANK_NAME_MAP[trimmedName]) {
    return BANK_NAME_MAP[trimmedName];
  }
  
  // 模糊匹配
  for (const [key, value] of Object.entries(BANK_NAME_MAP)) {
    if (trimmedName.includes(key) || key.includes(trimmedName)) {
      return value;
    }
  }
  
  return null;
}

/**
 * 验证银行卡号和银行名称是否匹配
 * @param {string} cardNumber 银行卡号
 * @param {string} bankName 银行名称
 * @returns {object} 验证结果
 */
function validateBankCard(cardNumber, bankName) {
  const result = {
    isValid: false,
    cardNumberValid: false,
    bankNameValid: false,
    bankMatch: false,
    detectedBank: null,
    standardizedBankName: null,
    errors: []
  };
  
  // 验证卡号格式
  result.cardNumberValid = luhnCheck(cardNumber);
  if (!result.cardNumberValid) {
    result.errors.push('银行卡号格式不正确');
  }
  
  // 识别银行
  result.detectedBank = getBankByBIN(cardNumber);
  
  // 标准化银行名称
  result.standardizedBankName = standardizeBankName(bankName);
  result.bankNameValid = result.standardizedBankName !== null;
  
  if (!result.bankNameValid) {
    result.errors.push('银行名称无法识别');
  }
  
  // 验证银行名称与卡号是否匹配
  if (result.detectedBank && result.standardizedBankName) {
    result.bankMatch = result.detectedBank === result.standardizedBankName;
    if (!result.bankMatch) {
      result.errors.push(`银行卡号归属${result.detectedBank}，与填写的${result.standardizedBankName}不匹配`);
    }
  } else if (result.detectedBank) {
    result.errors.push(`根据卡号识别为${result.detectedBank}，请确认银行名称`);
  }
  
  result.isValid = result.cardNumberValid && result.bankNameValid && (result.bankMatch || !result.detectedBank);
  
  return result;
}

/**
 * 获取所有支持的银行列表
 * @returns {Array} 银行列表
 */
function getSupportedBanks() {
  const banks = new Set();
  Object.values(BANK_BIN_MAP).forEach(bank => banks.add(bank));
  Object.values(BANK_NAME_MAP).forEach(bank => banks.add(bank));
  return Array.from(banks).sort();
}

/**
 * 格式化银行卡号显示
 * @param {string} cardNumber 银行卡号
 * @returns {string} 格式化后的卡号
 */
function formatCardNumber(cardNumber) {
  if (!cardNumber) return '';
  
  const cleanNumber = cardNumber.replace(/\D/g, '');
  return cleanNumber.replace(/(\d{4})(?=\d)/g, '$1 ');
}

export {
  luhnCheck,
  getBankByBIN,
  standardizeBankName,
  validateBankCard,
  getSupportedBanks,
  formatCardNumber,
  BANK_BIN_MAP,
  BANK_NAME_MAP
};

export default {
  luhnCheck,
  getBankByBIN,
  standardizeBankName,
  validateBankCard,
  getSupportedBanks,
  formatCardNumber,
  BANK_BIN_MAP,
  BANK_NAME_MAP
};